package edu.stanford.cs.cs294s;

import java.io.File;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;

import edu.stanford.concierge.Concierge;

public class MainActivity extends MapActivity {
	private static final int STOPSPLASH = 0;
	private static final long SPLASHTIME = 1000;
	private ImageView splash; 
	
    private static final int MENU_NEW_POI = 0;
	private static final int MENU_LAYERS = 1;
	private static final int MENU_YOUAREHERE = 2;
	private static final int MENU_SAT = 3;
	
	boolean isSatView = false;
	
	BalloonOverlay mItemizedoverlay;
	Projection mapProjection;
	private boolean isAddPoint = false;
	
	private MapController mapController;
	protected MapView mapView;
	
	private LocationManager lm;
	private LocationListener ll;
	GeoPoint current_location = null;

	private Handler splashHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case STOPSPLASH:
				splash.setVisibility(View.GONE);
				break;
			}
			super.handleMessage(msg);
		}
	}; 
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        splash();
        setup();
        
        //Folder
        File fpath = new File(Environment.getExternalStorageDirectory() + "/images");
        fpath.mkdir();
    }
    
	public void splash() {
		splash = (ImageView) findViewById(R.id.splashscreen);
		Message msg = new Message();
		msg.what = STOPSPLASH;
		splashHandler.sendMessageDelayed(msg, SPLASHTIME);
	}

    public void setup(){
    	System.err.println("Calling setup()");
        //Setting up mapview
        mapView = (MapView)findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
        mapView.setSatellite(false);
        
        //Creating the map marker
        List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.bluedot);
        mItemizedoverlay = new BalloonOverlay(drawable, mapView);
        mItemizedoverlay.setParentActivity(this);
        mapProjection = mapView.getProjection();
        
        /*
        mapView.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				System.err.println("In mapview touch listener isAddPoint : " + isAddPoint);
				if(isAddPoint){
					//TODO Auto-generated method stub
					System.err.println("touch x , y " + event.getX() + "," + event.getY());
					GeoPoint p = mapProjection.fromPixels((int)event.getX(), (int)event.getY());
					System.err.println("geopoint lat, lon " + p.getLatitudeE6() + "," + p.getLongitudeE6());
					isAddPoint = false;
				}
				return true;
			}
		});
        */
        
        //Get data from server
        ServerConnection sc = new ServerConnection("http://colby.stanford.edu/cs294s/location/get.php");
        List<Point> places = sc.getAllPoints();
        System.err.println("Points count : " + places.size());
        for(int i=0; i<places.size(); i++){
        	System.err.println("lat : " + places.get(i).getLatitude() + " lon : " + places.get(i).getLongitude()
        			+ " name: " + places.get(i).getName() + " facts : " + places.get(i).getFacts());
        	GeoPoint p = new GeoPoint(places.get(i).getLatitude(), places.get(i).getLongitude());
        	mItemizedoverlay.addOverlay(new OverlayItem(p, places.get(i).getName(), places.get(i).getFacts()), places.get(i));
        }
                
        mapOverlays.add(mItemizedoverlay);
        MyLocationOverlay myLocationOverlay = new MyLocationOverlay();
        mapOverlays.add(myLocationOverlay);
        
        lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        ll = new MyLocationListener();
        
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, ll);

        //Get the current location in start-up
        current_location = new GeoPoint(
        		(int)(lm.getLastKnownLocation(LocationManager.GPS_PROVIDER).getLatitude()*1000000),
               (int)(lm.getLastKnownLocation(LocationManager.GPS_PROVIDER).getLongitude()*1000000));
               
        //Move the map over Stanford and zoom appropriately
        //GeoPoint point = new GeoPoint(37430160,-122173591);
       
        mapController = mapView.getController();
        mapController.animateTo(current_location);
        mapController.setZoom(16);
    }
    
    protected void ToggleView(){
    	mapView.setSatellite(isSatView);
    	isSatView = !isSatView;
    }
    
    protected void GoToLocation(GeoPoint point){
        mapController.animateTo(point);
        mapController.setZoom(16);
    }
    
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	/* Creates the menu items */
	public boolean onCreateOptionsMenu(Menu menu) {
	    menu.add(0, MENU_NEW_POI, 0, "Add Location").setIcon(R.drawable.addicon);
	    menu.add(0, MENU_LAYERS, 0, "Layers").setIcon(R.drawable.mapicon);
	    menu.add(0, MENU_YOUAREHERE, 0, "You Are Here").setIcon(R.drawable.mapicon);
	    menu.add(0, MENU_SAT, 0, "Toggle Map/Satellite View").setIcon(R.drawable.mapicon);
	    return true;
	}

	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
	    switch (item.getItemId()) {
	    case MENU_NEW_POI:
	        callCameraActivity();
	        //isAddPoint = true;
	        //mItemizedoverlay.viewButton = true;
	        return true;
	    case MENU_LAYERS:
	        //showLayers();
	        //mItemizedoverlay.viewButton = false;
	        return true;
	    case MENU_YOUAREHERE:
	    	GoToLocation(current_location);
	    	return true;
	    case MENU_SAT:
	    	ToggleView();
	    	return true;
	    }
	    return false;
	}

	public void showPointInfo(Point point) {
		// TODO Auto-generated method stub
		//Intent getId = new Intent();
		//getId.setClassName("edu.stanford.cs.cs294s", "edu.stanford.cs.cs294s.LocationTabWidget");
		//startActivityForResult(getId, 1002);
		
		Intent i = new Intent(getBaseContext(), LocationTabWidget.class);
		System.err.println("showPointInfo : " + point.getName() + "," + point.getIndex());
		i.putExtra("name", point.getName());
		i.putExtra("index", Integer.toString(point.getIndex()));
		i.putExtra("facts", point.getFacts());
		startActivityForResult(i, 100);
	}

	private void callCameraActivity() {
		// TODO Auto-generated method stub
		Intent getId = new Intent();
		getId.setClassName("edu.stanford.cs.cs294s", "edu.stanford.cs.cs294s.AddPoint");
		startActivityForResult(getId, 1002);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		System.err.println("Got result requestCode : " + requestCode + " resultCode : " + resultCode );
		if(requestCode == 100){
			//System.err.println("Got the result - refreshing");
			setup();
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		System.err.println("In touch event isAddPoint : " + isAddPoint);
		if(isAddPoint){
			//TODO Auto-generated method stub
			System.err.println("touch x , y " + event.getX() + "," + event.getY());
			GeoPoint p = mapProjection.fromPixels((int)event.getX(), (int)event.getY());
			System.err.println("geopoint lat, lon " + p.getLatitudeE6() + "," + p.getLongitudeE6());
			isAddPoint = false;
		}
		return true;
		//return super.onTouchEvent(event);
	}
	
	protected class MyLocationOverlay extends com.google.android.maps.Overlay {

	    public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
	        Paint paint = new Paint();

	        super.draw(canvas, mapView, shadow);
	        // Converts lat/lng-Point to OUR coordinates on the screen.
	        android.graphics.Point myScreenCoords = new android.graphics.Point();

	        mapView.getProjection().toPixels(current_location, myScreenCoords);

	        paint.setStrokeWidth(1);
	        paint.setARGB(255, 255, 255, 255);
	        paint.setStyle(Paint.Style.STROKE);

	        Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.androidmarker);

	        canvas.drawBitmap(bmp, myScreenCoords.x, myScreenCoords.y, paint);
	        canvas.drawText("YOU ARE HERE", myScreenCoords.x, myScreenCoords.y, paint);
	        return true;
	    }
	}
	
	private class MyLocationListener implements LocationListener{
	    public void onLocationChanged(Location argLocation) {
	     // TODO Auto-generated method stub
	     GeoPoint myGeoPoint = new GeoPoint(
	      (int)(argLocation.getLatitude()*1000000),
	      (int)(argLocation.getLongitude()*1000000));
	     /*
	      * it will show a message on 
	      * location change
	     Toast.makeText(getBaseContext(),
	             "New location latitude [" +argLocation.getLatitude() +
	             "] longitude [" + argLocation.getLongitude()+"]",
	             Toast.LENGTH_SHORT).show();
	      */

	     mapController.animateTo(myGeoPoint);

	    }

	    public void onProviderDisabled(String provider) {
	     // TODO Auto-generated method stub
	    }

	    public void onProviderEnabled(String provider) {
	     // TODO Auto-generated method stub
	    }

	    public void onStatusChanged(String provider,
	      int status, Bundle extras) {
	     // TODO Auto-generated method stub
	    }
	}    
}